﻿using System;
using System.Linq;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using WindowsGame1.Objects3D;
using System.Collections;
using System.Collections.Generic;
namespace WindowsGame1.Operations
{
    class Map
    {
         public const short CODE_FREE = 0;
         public const short CODE_WALL = 1;
         public const  short CODE_ENTRANCE = 2;
         public const short CODE_EXIT = 3;
         public const short CODE_EXTRATIME = 4;
        clsPlane plano;
        private int width=0, height=0;
        private float wallWidth, wallDepth, wallHeight = 1.0f;
        short[,] array;
        float[] start;

        private GraphicsDevice GraphicsDevice;
        private Microsoft.Xna.Framework.Content.ContentManager Content;
        private List<clsManualCube> cubes = new List<clsManualCube>();
        private List<clsCube> _powerUps = new List<clsCube>();
        private Texture2D texture;
        public Map(GraphicsDevice GraphicsDevice, Microsoft.Xna.Framework.Content.ContentManager Content)
        {
            this.GraphicsDevice = GraphicsDevice;
            this.Content = Content;
            plano = new clsPlane(GraphicsDevice);
            texture = Content.Load<Texture2D>("Brickwall");
        }

        public void load(string file)
        {
	      //create a string variable to hold the file contents
		 string fileContents = string.Empty;
		 //create a new TextReader then open the file
		 TextReader reader = new StreamReader(file);
		  //loop through the entire file
         
         int x = 0, y = 0;
		  while (reader.Peek() != -1)
		  {
              String line = reader.ReadLine().ToString();
              if (array == null)
              {
                  String[] split = line.Split('x');
                  width = Convert.ToInt32(split[0]);
                  height = Convert.ToInt32(split[1]);
                  plano.CreatePlane(0,0,getWidth(), getHeight());
                  plano.LoadContent(Content.Load<Texture2D>("PlaneTexture"));
                  wallWidth = plano.getWidth() / width;
                  wallDepth = plano.getHeight() / height;
                  array = new short[width, height];
              }
              else
              {
                  for (int i = 0; i < line.Length;i++)
                  {
                      Char element = line.ElementAt(i);
                      if('x'.Equals(element)){
                          array[x, y] = CODE_WALL;
                          clsManualCube cube = new clsManualCube(GraphicsDevice,x*wallWidth,0,y*wallDepth,wallWidth*2,wallHeight/2,wallDepth*2,texture);
                          cubes.Add(cube);
                      }
                      else if ('0'.Equals(element))
                      {
                          array[x, y] = CODE_ENTRANCE;
                          start = new float[2];
                          start[0] = (x * wallWidth);
                          start[1] = (y * wallDepth + (wallDepth*2));
                      }
                      else if ('1'.Equals(element))
                      {
                          array[x, y] = CODE_EXIT ;
                      } 
                      else if ('2'.Equals(element))
                      {
                          array[x, y] = CODE_EXTRATIME;
                          clsCube cube = new clsCube(GraphicsDevice, x, y, new Vector3(x * (wallDepth * 2), 0, y * (wallDepth * 2)), new Vector3(wallWidth / 2, 10, wallWidth / 2));
                          _powerUps.Add(cube);
                          Console.WriteLine("x: "+x+" y: "+y+" wallWidth: "+wallWidth+" wallDepth: "+wallDepth);
                      }
                      else
                      {
                          array[x, y] = CODE_FREE;
                      }
                      x++;
                  }
                  x = 0;
                  y++;
              }
		  }
          reader.Close();
          
          cubes.Sort(compareZ);
//          cubes.Sort(compareX);
          
        }

        public void Draw()
        {
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            plano.Draw();
            for (int i = 0; i < cubes.Count; i++)
            {
                clsManualCube cube = (clsManualCube)cubes[i];
                cube.Draw();
            }

            for (int i = 0; i < _powerUps.Count; i++)
            {
                clsCube cube = _powerUps[i];
                cube.Draw();
            }
        }

        public Boolean isWall(int x, int y)
        {
            return array[x, y] == CODE_WALL;
        }

        public void SetItFree(int x, int y)
        {
            for (int i = 0; i < _powerUps.Count; i++)
            {
                clsCube cube = _powerUps[i];
                if(cube.X == x && cube.Y == y)
                    _powerUps.RemoveAt(i);
            }
            array[x, y] = CODE_FREE;
        }

        public Boolean isFree(int x, int y)
        {
            return array[x, y] == CODE_FREE;
        }

        public Boolean isExtraTime(int x, int y)
        {
            return array[x, y] == CODE_EXTRATIME;
        }

        public Boolean isExit(int x, int y)
        {
            return array[x, y] == CODE_EXIT;
        }

        public int getWidth()
        {
            return width;
        }

        public int getHeight()
        {
            return height;
        }


        internal void UnloadContent()
        {
            plano.UnloadContent();
        }

        public static int compareZ(clsManualCube cube, clsManualCube otherCube)
        {
            if (otherCube.getZ() > cube.getZ())
            {
                return 1;
            }
            return 0;
        }

        public static int compareX(clsManualCube cube, clsManualCube otherCube)
        {
            if (otherCube.getX() < cube.getX())
            {
                return 1;
            }
            return 0;
        }

        public int getIndexForPositionX(float x)
        {
            return (int)(x / (wallWidth * 2));
        }

        public int getIndexForPositionZ(float z)
        {
            return (int)(z/ (wallDepth*2));
        }

        public float[] getStart()
        {
            return start;
        }
    }
}
